#include <common.h>
#include <print.h>
#include <irq.h>
#include <8259A.h>
#include <task.h>
#include <desc.h>
#include <share.h>
#include <list.h>
#include <queue.h>


TASK taskA = {0};     // 任务对象
U08 taskA_stack[512];   // 任务私有栈
void TaskAFunc(void)    // 任务执行函数
{
    static U32 count = 0;
    while(1)
    {
        if(count++ % 100000 == 0)
        {
            static U32 j = 0;
            asm volatile("cli");
            SetCursorPos(0, 6);
            printk("TASK A: %d\n", j++); 
            asm volatile("sti");
        }  
    }
}

TASK taskB = {0};     // 任务对象
U08 taskB_stack[512];   // 任务私有栈
void TaskBFunc(void)    // 任务执行函数
{
    static U32 count = 0;
    while(1)
    {
        if(count++ % 500000 == 0)
        {
            static U32 j = 0;
            asm volatile("cli");
            SetCursorPos(0, 8);
            printk("TASK B: %c\n", (j++%26)+'A'); 
            asm volatile("sti"); 
        }  
    }
}

TASK taskC = {0};     // 任务对象
U08 taskC_stack[512];   // 任务私有栈
void TaskCFunc(void)    // 任务执行函数
{
    static U32 count = 0;
    while(1)
    {
        if(count++ % 500000 == 0)
        {
            static U32 j = 0;
            asm volatile("cli");
            SetCursorPos(0, 10);
            printk("TASK C: %c\n", (j++%26)+'a'); 
            asm volatile("sti"); 
        }  
    }
}

TASK taskD = {0};     // 任务对象
U08 taskD_stack[512];   // 任务私有栈
void TaskDFunc(void)    // 任务执行函数
{
    static U32 count = 0;
    while(1)
    {
        if(count++ % 100000 == 0)
        {
            static U32 j = 0;
            asm volatile("cli");
            SetCursorPos(0, 12);
            printk("TASK D: %x\n", j++); 
            asm volatile("sti");
        }  
    }
}

typedef struct TASK_LIST_NODE
{
    LIST_NODE     listNode;
    TASK*         task;
} TASK_LIST_NODE;

LIST TASK_LIST;

typedef struct TASK_QUEUE_NODE
{
    LIST_NODE     listNode;
    TASK*         task;
} TASK_QUEUE_NODE;

QUEUE TASK_QUEUE;


S32 main(void)
{
    asm volatile("cli");                    // 关中断
    SetCursorPos(0, 2);                     // 设置光标位置: (0, 2)
    SetFontColor(E_FONT_WHITE);             // 设置打印字体颜色: 白色
    printk("Start kernel...\n");            // 打印字符串 "Start kernel..."
    IrqInit();                              // 中断请求初始化，绑定默认中断服务程序
    pic_init();                             // 初始化可编程中断控制器 8259A - 级联

    TaskCreat(&taskA, TaskAFunc, taskA_stack, 512, "Task A");   // 创建任务 TASK A
    TaskCreat(&taskB, TaskBFunc, taskB_stack, 512, "Task B");   // 创建任务 TASK B
    TaskCreat(&taskC, TaskCFunc, taskC_stack, 512, "Task C");   // 创建任务 TASK C
    TaskCreat(&taskD, TaskDFunc, taskD_stack, 512, "Task D");   // 创建任务 TASK D

    printk("------------------list test--------------------\n");
    ListInit(&TASK_LIST);

    static TASK_LIST_NODE taskListNodeA;
    taskListNodeA.task = &taskA;
    ListAddHead(&TASK_LIST, (LIST_NODE *)&taskListNodeA);

    static TASK_LIST_NODE taskListNodeB;
    taskListNodeB.task = &taskB;
    ListAddHead(&TASK_LIST, (LIST_NODE *)&taskListNodeB);

    static TASK_LIST_NODE taskListNodeC;
    taskListNodeC.task = &taskC;
    ListAddHead(&TASK_LIST, (LIST_NODE *)&taskListNodeC);

    static TASK_LIST_NODE taskListNodeD;
    taskListNodeD.task = &taskD;
    ListAddHead(&TASK_LIST, (LIST_NODE *)&taskListNodeD);

    LIST_NODE* pListNode = NULL;
    LIST_FOR_EACH(&TASK_LIST, pListNode)
    {
        TASK_LIST_NODE* nodeTmp = (TASK_LIST_NODE *)LIST_NODE(pListNode,  TASK_LIST_NODE, listNode);
        printk("%s\n", nodeTmp->task->name);
    }

    printk("------------------delete last list node--------------------\n");
    ListDelNode(TASK_LIST.prev);   // 删掉最后一个
    LIST_FOR_EACH(&TASK_LIST, pListNode)
    {
        TASK_LIST_NODE* nodeTmp = (TASK_LIST_NODE *)LIST_NODE(pListNode,  TASK_LIST_NODE, listNode);
        printk("%s\n", nodeTmp->task->name);
    }

    printk("------------------queue test--------------------\n");
    QueueInit(&TASK_QUEUE);

    static TASK_QUEUE_NODE taskQueueNodeA;
    taskQueueNodeA.task = &taskA;
    QueueAdd(&TASK_QUEUE, (QUEUE_NODE *)&taskQueueNodeA);

    static TASK_QUEUE_NODE taskQueueNodeB;
    taskQueueNodeB.task = &taskB;
    QueueAdd(&TASK_QUEUE, (QUEUE_NODE *)&taskQueueNodeB);

    static TASK_QUEUE_NODE taskQueueNodeC;
    taskQueueNodeC.task = &taskC;
    QueueAdd(&TASK_QUEUE, (QUEUE_NODE *)&taskQueueNodeC);

    static TASK_QUEUE_NODE taskQueueNodeD;
    taskQueueNodeD.task = &taskD;
    QueueAdd(&TASK_QUEUE, (QUEUE_NODE *)&taskQueueNodeD);

    QUEUE_NODE* pQueueNode = NULL;
    while(TASK_QUEUE.length)
    {
        QUEUE_NODE* nodeTmp = QueueRemove(&TASK_QUEUE);
        TASK_QUEUE_NODE* queueNodeTmp = (TASK_QUEUE_NODE *)QUEUE_NODE(nodeTmp, TASK_QUEUE_NODE, listNode);
        printk("%s\n", queueNodeTmp->task->name);
    }

    // TaskStart(&taskA);

    while(1);
    return 0;
}